package top.mcwebsite.playandroid.business.tutorial.impl.vm

import androidx.lifecycle.viewModelScope
import androidx.paging.*
import kotlinx.coroutines.Dispatchers
import top.mcwebsite.playandroid.business.articles.api.model.ArticleModel
import top.mcwebsite.playandroid.business.tutorial.impl.api.TutorialApi
import top.mcwebsite.playandroid.common.network.api.NetworkService
import top.mcwebsite.playandroid.common.network.api.createApi
import top.mcwebsite.playandroid.common.network.model.PageModel
import top.mcwebsite.playandroid.common.network.model.RespModel
import top.mcwebsite.playandroid.lib.mvi.base.BaseViewModel
import top.mcwebsite.playandroid.lib.servicemanager.core.ServiceManager
import java.lang.RuntimeException

class TutorialMenuViewModel : BaseViewModel<TutorialMenuIntent, TutorialMenuUiState, TutorialMenuUiEffect>(
    TutorialMenuUiState()
) {

    private val tutorialApi = ServiceManager.getService<NetworkService>().createApi<TutorialApi>()

    private val pager = Pager(PagingConfig(pageSize = 20)) { TutorialMenuPagingSource() }
    val pagerFlow = pager.flow.cachedIn(viewModelScope)

    override fun handleIntent(intent: TutorialMenuIntent) {
        when (intent) {
            is TutorialMenuIntent.InitTutorialMenuIntent -> {
                init(intent)
            }
            is TutorialMenuIntent.RequestToTutorialDetailPageIntent -> {
                sendUiEffect(TutorialMenuUiEffect.NavigationToDetailPageEffect(intent.articleModel))
            }
        }
    }

    private fun init(intent: TutorialMenuIntent.InitTutorialMenuIntent) {
        val tutorialModel = intent.tutorialModel
        if (tutorialModel == null) {
            // TODO show error
        } else {
            setUiState { copy(tutorialModel = intent.tutorialModel, pagerFlow = this@TutorialMenuViewModel.pagerFlow) }
        }
    }


    private suspend fun fetchTutorialMenu(page: Int, cid: Long): RespModel<PageModel<ArticleModel>> {
        return with(Dispatchers.IO) {
            tutorialApi.getTutorialMenus(page, cid)
        }
    }

    inner class TutorialMenuPagingSource : PagingSource<Int, ArticleModel>() {
        override fun getRefreshKey(state: PagingState<Int, ArticleModel>): Int? {
            return null
        }

        override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ArticleModel> {
            return try {
                val nextPageNumber = params.key ?: 0
                if (uiState.tutorialModel != null) {
                    val data = fetchTutorialMenu(nextPageNumber, uiState.tutorialModel!!.id)
                    LoadResult.Page(
                        data = data.data?.datas ?: emptyList(),
                        prevKey = if (nextPageNumber == 0) null else nextPageNumber - 1,
                        nextKey = if (data.data?.datas.isNullOrEmpty()) null else nextPageNumber + 1
                    )
                } else {
                    LoadResult.Error(RuntimeException("未知错误"))
                }
            } catch (e: Exception) {
                return LoadResult.Error(e)
            }
        }

    }
}